package cn.kgc.websocket;

import cn.hutool.core.collection.CollUtil;
import io.netty.channel.Channel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author YC
 */
public class UserChannelSession {

    /**
     * 保存用户的会话 key是用户ID value是当前所有存活的Channel集合
     */
    private static final Map<String, List<Channel>> MULTI_SESSION = new HashMap<>();
    /**
     * 保存用户通道ID key是Channel_ID value是用户ID
     * //假设用户A 现在使用手机端和平板端和服务器建立链接（服务端需要记录两个channel）。
     * //如果用户关闭了手机端的APP, 服务端移除掉手机端的链接(channel)
     * //在服务器中如何能够知道关闭channel是哪个用户的呢?
     * //key是channelId  value是用户的ID
     * //根据关闭的channelId获得对应的用户ID,根据用户ID可以获得用户原来拥有的channel集合。
     * //从channel集合中移除掉被关闭的channel,那么channel集合剩下存储的就是所有存活的Channel。
     */
    private static final Map<String, String> USER_CHANNEL_ID_MAP = new HashMap<>();

    /**
     * 添加用户通道
     *
     * @param userId  用户ID
     * @param channel 通道
     */
    public static void putMultiChannels(String userId, Channel channel) {
        List<Channel> channels = MULTI_SESSION.get(userId);
        if (CollUtil.isEmpty(channels)) {
            // 如果用户没有通道集合创建新的通道集合
            channels = new ArrayList<>();
        }
        // 向通道集合中添加新的通道
        if (!channels.contains(channel)) {
            channels.add(channel);
        }
        MULTI_SESSION.put(userId, channels);
    }

    /**
     * 获得用户的所有通道
     *
     * @param userId 用户ID
     */
    public static List<Channel> getMultiChannels(String userId) {
        return MULTI_SESSION.get(userId);
    }

    /**
     * channelID与userID对应关系
     *
     * @param channelId 通道ID
     * @param userId    用户ID
     */
    public static void putUserChannelId(String channelId, String userId) {
        USER_CHANNEL_ID_MAP.put(channelId, userId);
    }

    /**
     * 根据channelID获得userID
     *
     * @param channelId 通道ID
     * @return 用户ID
     */
    public static String getUserId(String channelId) {
        return USER_CHANNEL_ID_MAP.get(channelId);
    }

    /**
     * 从用户ID对应的所有通道中删除用户关闭的通道
     *
     * @param channelId 通道ID
     */
    public static void removeUselessChannel(String channelId) {
        // 获得用户ID
        String userId = getUserId(channelId);
        // 获得用户的所有通道
        List<Channel> multiChannels = getMultiChannels(userId);
        // 从用户的所有通道中删除用户关闭的通道
        multiChannels.removeIf(multiChannel -> multiChannel.id().asLongText().equals(channelId));
        // 将没有关闭的通道重新保存到MULTI_SESSION ，如果用户关闭通道后MULTI_SESSION为空则删除用户通道集合
        if (CollUtil.isEmpty(multiChannels)) {
            MULTI_SESSION.remove(userId);
        }
        MULTI_SESSION.put(userId, multiChannels);
        // 移除关闭的通道与用户的关系
        USER_CHANNEL_ID_MAP.remove(channelId);
    }

    /**
     * 打印用户ID及用户ID对应的所有通道ID
     */
    public static void print(String str) {
        System.out.println("=====================================================================================");
        System.out.println(str);
        MULTI_SESSION.forEach((userId, channels) -> {
            System.out.println("用户ID：" + userId);
            channels.forEach(channel -> System.out.println("通道ID：" + channel.id().asLongText()));
        });
        System.out.println("=====================================================================================");
    }

}

